package com.rickpan.scheduler;

import com.rickpan.entity.User;
import com.rickpan.entity.VipSubscription;
import com.rickpan.repository.UserRepository;
import com.rickpan.service.PaymentService;
import com.rickpan.service.VipFeatureService;
import com.rickpan.service.VipSubscriptionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;

/**
 * VIP过期处理定时任务
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class VipExpirationScheduler {

    private final UserRepository userRepository;
    private final VipSubscriptionService subscriptionService;
    private final PaymentService paymentService;
    private final VipFeatureService featureService;

    /**
     * 检查VIP过期状态 - 每天凌晨2点执行
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void checkVipExpiration() {
        log.info("开始执行VIP过期检查定时任务");

        LocalDateTime now = LocalDateTime.now();
        LocalDateTime sevenDaysLater = now.plusDays(7);

        try {
            // 1. 处理已过期用户
            List<User> expiredUsers = userRepository.findExpiredVipUsers(now);
            for (User user : expiredUsers) {
                processExpiredUser(user);
            }

            // 2. 发送即将过期提醒
            List<User> expiringUsers = userRepository.findExpiringVipUsers(now, sevenDaysLater);
            for (User user : expiringUsers) {
                sendExpirationReminder(user);
            }

            // 3. 处理过期订阅
            subscriptionService.handleExpiredSubscriptions();

            // 4. 处理过期订单
            paymentService.handleExpiredOrders();

            log.info("VIP过期检查完成，处理{}个已过期用户，{}个即将过期用户",
                    expiredUsers.size(), expiringUsers.size());

        } catch (Exception e) {
            log.error("VIP过期检查任务执行失败", e);
        }
    }

    /**
     * 清理过期数据 - 每周日凌晨3点执行
     */
    @Scheduled(cron = "0 0 3 * * SUN")
    public void cleanupExpiredData() {
        log.info("开始执行过期数据清理任务");

        try {
            // 清理过期的功能使用记录
            featureService.cleanupExpiredRecords();
            
            log.info("过期数据清理任务完成");
        } catch (Exception e) {
            log.error("过期数据清理任务执行失败", e);
        }
    }

    /**
     * VIP用户统计报告 - 每天上午9点执行
     */
    @Scheduled(cron = "0 0 9 * * ?")
    public void generateVipStatisticsReport() {
        log.info("开始生成VIP用户统计报告");

        try {
            LocalDateTime now = LocalDateTime.now();
            
            // 统计VIP用户数量
            Long totalVipUsers = userRepository.countVipUsers();
            Long activeVipUsers = userRepository.countActiveVipUsers(now);
            Long basicUsers = userRepository.countBasicUsers();

            // 统计即将过期的VIP用户
            List<VipSubscription> expiringSubscriptions = subscriptionService.getExpiringSubscriptions();

            log.info("=== VIP用户统计报告 ===");
            log.info("总VIP用户数: {}", totalVipUsers);
            log.info("活跃VIP用户数: {}", activeVipUsers);
            log.info("BASIC用户数: {}", basicUsers);
            log.info("7天内即将过期VIP订阅数: {}", expiringSubscriptions.size());
            log.info("=====================");

        } catch (Exception e) {
            log.error("生成VIP统计报告失败", e);
        }
    }

    /**
     * 处理已过期用户
     */
    private void processExpiredUser(User user) {
        try {
            // 注意：不直接在这里降级用户，因为用户可能有多个订阅
            // 降级逻辑在 VipSubscriptionService.handleExpiredSubscriptions() 中处理
            log.info("检测到过期VIP用户: {} (过期时间: {})", 
                    user.getUsername(), user.getVipExpireTime());
        } catch (Exception e) {
            log.error("处理过期用户失败: userId={}", user.getId(), e);
        }
    }

    /**
     * 发送即将过期提醒
     */
    private void sendExpirationReminder(User user) {
        try {
            long daysLeft = ChronoUnit.DAYS.between(LocalDateTime.now(), user.getVipExpireTime());
            
            // 简化版：记录日志，实际项目中可以发送邮件/短信/站内信
            log.info("VIP即将过期提醒: 用户 {} 的VIP将在{}天后过期 ({})", 
                    user.getUsername(), daysLeft, user.getVipExpireTime());
            
            // TODO: 集成邮件服务发送提醒邮件
            // TODO: 集成短信服务发送提醒短信
            // TODO: 创建站内消息提醒
            
        } catch (Exception e) {
            log.error("发送过期提醒失败: userId={}", user.getId(), e);
        }
    }
}